package com.ehome.poct.terminal.service;

import cn.hutool.core.util.StrUtil;
import com.ehome.core.page.Page;
import com.ehome.core.page.PageInfo;
import com.ehome.exception.BizException;
import com.ehome.poct.base.api.constant.BizCode;
import com.ehome.poct.base.api.dto.doctor.TermClinicDTO;
import com.ehome.poct.base.api.dto.sys.MqttMsg;
import com.ehome.poct.base.api.feign.ClinicClient;
import com.ehome.poct.base.api.feign.sys.MqttClient;
import com.ehome.poct.core.api.dto.DelReportDTO;
import com.ehome.poct.core.api.dto.ReportListDTO;
import com.ehome.poct.core.api.dto.ReportQry;
import com.ehome.poct.core.api.dto.check.BaseMsgDTO;
import com.ehome.poct.core.api.dto.check.CheckReportDTO;
import com.ehome.poct.core.api.dto.check.ReportDTO;
import com.ehome.poct.core.api.dto.report.*;
import com.ehome.poct.core.api.feign.OrderClient;
import com.ehome.poct.core.api.feign.PatientClient;
import com.ehome.poct.core.api.feign.ReportClient;
import com.ehome.poct.core.api.vo.CheckReportPageVO;
import com.ehome.poct.core.api.vo.CheckReportVO;
import com.ehome.poct.core.api.vo.ReportDetailVO;
import com.ehome.poct.core.api.vo.ReportListVO;
import com.ehome.poct.core.api.vo.report.TestReportConfRecordVO;
import com.ehome.poct.core.api.vo.report.TestReportConfVO;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.AllArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * @description:
 * @author: muqiu
 * @time: 2022/3/18 10:36
 */
@AllArgsConstructor
@Service
public class BldReportServiceImpl implements ReportService {

    private final ReportClient reportClient;

    private final ClinicClient clinicClient;

    private static final Integer INVALID = 24;

    private final MqttClient mqttClient;

    private final ObjectMapper objectMapper;

    private final OrderClient orderClient;

    private final PatientClient patientClient;

    @Override
    public CheckReportPageVO list(ReportListDTO dto) {
        ReportQry reportQry = new ReportQry();
        BeanUtils.copyProperties(dto, reportQry);
        final var expiredTime = LocalDateTime.now().minusDays(1);
        if(dto.getPayStatus() != null) {
            if (dto.getPayStatus() == -1) {
                reportQry.setPayStatus(0);
                // 查询的结束时间超过了未支付过期时间
                if (dto.getEndTime().isAfter(expiredTime)) {
                    reportQry.setEndTime(expiredTime);
                }
            }
            if (dto.getPayStatus() == 0) {
                reportQry.setStartTime(expiredTime.isAfter(dto.getStartTime()) ? expiredTime : dto.getStartTime());
            }
        }
        reportQry.setSortColumns("createTime desc");
        Page<CheckReportVO> page = reportClient.page(reportQry);

        List<ReportListVO> list = new ArrayList<>();
        page.getList().forEach(r -> {
            ReportListVO reportListVO = new ReportListVO();
            reportListVO.setReportId(r.getBloodCheckReportId());
            reportListVO.setReportName(r.getReportName());
            reportListVO.setPayOrderNo(r.getOrderNo());
            reportListVO.setCreateTime(r.getCreateTime());
            //患者姓名
            if(r.getPatientId() != null){
                var patient = patientClient.getByPatientId(r.getPatientId());
                if(patient != null){
                    reportListVO.setPatientName(patient.getName());
                }
            }
            reportListVO.setUrl("https://patienttest.ehomepoct.com/#/hard/hardwarereport?type=1&id="+ r.getOrderNo());
            this.getOrderStatus(r, reportListVO);
            list.add(reportListVO);
        });
        //查询未支付数量的结束时间
        reportQry.setStartTime(expiredTime.isAfter(dto.getStartTime()) ? expiredTime : dto.getStartTime());
        reportQry.setEndTime(dto.getEndTime());
        return new CheckReportPageVO(this.getCount(reportQry), list);
    }

    @Override
    public void deleteById(DelReportDTO delReportDTO) {
        reportClient.deleteBld(delReportDTO.getReportId());
    }

    public Integer getCount(ReportQry reportQry){
        reportQry.setPayStatus(0);
        Page<CheckReportVO> page = reportClient.page(reportQry);
        return page.getTotal();
    }

    /**
     * 订单状态
     *
     * @param checkReportVO
     * @param reportListVO
     * @return
     */
    public void getOrderStatus(CheckReportVO checkReportVO, ReportListVO reportListVO) {
        if (checkReportVO.getPayStatus() == 0) {
            Duration duration = Duration.between(checkReportVO.getCreateTime(), LocalDateTime.now());
            if (duration.toHours() > INVALID) {
                reportListVO.setPayStatus(-1);
                return;
            }
            reportListVO.setPayStatus(0);
            reportListVO.setInvalidTime(24 * 3600 - duration.toSeconds());
            return;
        }
        reportListVO.setPayStatus(20);
    }

    @Override
    public ReportDetailVO getOneByOrderNoPrint(String orderNo, Boolean local){
        final var reportDetailVO = reportClient.getCheckReportByOrderNo(orderNo);
        final var clinicDTO = clinicClient.getById(reportDetailVO.getPatient().getClinicId());
        reportDetailVO.setClinicName(clinicDTO.getName());
        if(local){
            //根据订单获取报告内容
            return reportDetailVO;
        }
        try {
            System.out.println(objectMapper.writeValueAsString(createBaseMsgDTO(reportDetailVO)));
            //发送mqtt消息
            mqttClient.sendToMqtt(new MqttMsg().setData(objectMapper.writeValueAsString(createBaseMsgDTO(reportDetailVO))).setTopic("ehome_clinic_mqtt_msg_" + clinicDTO.getTermClinicId()));
        } catch (JsonProcessingException e) {
            throw new BizException(BizCode.JSON_PROCESSING_ERROR);
        }
        return new ReportDetailVO();
    }

    private BaseMsgDTO<ReportDetailVO> createBaseMsgDTO(ReportDetailVO report) {
        return new BaseMsgDTO<ReportDetailVO>().setType(3).setTitle("血常规打印报告信息").setPubAuthor("blood").setPublishTime(LocalDateTime.now()).setReceivePackageId("com.ehome.health.gold").setData(report);
    }

    @Override
    public void toSendStatus(Long clinicId, String status){
        try {
        //发送mqtt消息
        mqttClient.sendToMqtt(new MqttMsg().setData(objectMapper.writeValueAsString(createBaseMsgDTO(status))).setTopic("ehome_clinic_mqtt_msg_" + clinicId));
        } catch (JsonProcessingException e) {
            throw new BizException(BizCode.JSON_PROCESSING_ERROR);
        }
    }

    @Override
    public void createReport(ReportReqDTO dto) {
        if (StrUtil.isBlank(dto.getOrderNo())) {
            final var report = reportClient.createByDataId(dto.getTestDataIds().get(0), dto.getOrderNo(), Boolean.TRUE);
            return;
        }
        checkOrderStatus(dto.getOrderNo(), orderClient);
        reportClient.createByDataId(dto.getTestDataIds().get(0), dto.getOrderNo(), Boolean.TRUE);
    }

    @Override
    public List<ReportDTO> getSummary(String orderNo) {
        List<ReportDTO> list = new ArrayList<>();
        var reportList = reportClient.getSummaryBld(new CheckReportDTO().setOrderNo(orderNo));
        reportList.forEach(r -> list.add(createReportDTO(r)));
        return list;
    }

    @Override
    public void reportConf(ReportConfigDTO reportConfigDTO) {
        //诊所相关信息
        var clinic = clinicClient.getOne(new TermClinicDTO().setPhone(reportConfigDTO.getAccount()));
        reportClient.reportConfigBld(new TestReportConfigDTO().setClinicId(clinic.getTermClinicId()).setStartTime(reportConfigDTO.getStartTime()).setEndTime(reportConfigDTO.getEndTime()).setDisabled(reportConfigDTO.getReportStatus() == 0 ? 1 : 0));
    }

    @Override
    public PageInfo<TestReportConfVO> reportConfPage(ReportConfigQry reportConfigQry) {
        return null;
    }

    @Override
    public PageInfo<TestReportConfRecordVO> reportConfRecord(ReportConfigRecordDTO reportConfigRecordDTO) {
        return null;
    }

    @Override
    public ClinicInfoVO clinicInfo(String account) {
        return null;
    }

    private ReportDTO createReportDTO(CheckReportVO r) {
       return new ReportDTO().setReportName(r.getReportName()).setReportId(r.getBloodCheckReportId()).setReportType(r.getReportType()).setStripTypeCode(r.getProjectCode());
    }

    private BaseMsgDTO<String> createBaseMsgDTO(String status) {
        return new BaseMsgDTO<String>().setType(7).setTitle("血常规连接打印机状态").setReceivePackageId("com.ehome.health.gold").setPublishTime(LocalDateTime.now()).setPubAuthor("blood").setData(status);
    }
}